home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / misc / AmigaSDLsrc.lha / amisrc / SDL_blit_1.c < prev    next >
C/C++ Source or Header  |  2001-04-29  |  11KB  |  531 lines

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23. #ifdef SAVE_RCSID
  24. static char rcsid =
  25.  "@(#) $Id: SDL_blit_1.c,v 1.3.2.6 2001/02/10 07:20:05 hercules Exp $";
  26. #endif
  27.  
  28. #include <stdio.h>
  29.  
  30. #include "SDL_types.h"
  31. #include "SDL_video.h"
  32. #include "SDL_blit.h"
  33. #include "SDL_sysvideo.h"
  34. #include "SDL_endian.h"
  35.  
  36. /* Functions to blit from 8-bit surfaces to other surfaces */
  37.  
  38. static void Blit1to1(SDL_BlitInfo *info)
  39. {
  40. #ifndef USE_DUFFS_LOOP
  41.     int c;
  42. #endif
  43.     int width, height;
  44.     Uint8 *src, *map, *dst;
  45.     int srcskip, dstskip;
  46.  
  47.     /* Set up some basic variables */
  48.     width = info->d_width;
  49.     height = info->d_height;
  50.     src = info->s_pixels;
  51.     srcskip = info->s_skip;
  52.     dst = info->d_pixels;
  53.     dstskip = info->d_skip;
  54.     map = info->table;
  55.  
  56.     while ( height-- ) {
  57. #ifdef USE_DUFFS_LOOP
  58.         DUFFS_LOOP(
  59.             {
  60.               *dst = map[*src];
  61.             }
  62.             dst++;
  63.             src++;
  64.         , width);
  65. #else
  66.         for ( c=width; c; --c ) {
  67.                 *dst = map[*src];
  68.             dst++;
  69.             src++;
  70.         }
  71. #endif
  72.         src += srcskip;
  73.         dst += dstskip;
  74.     }
  75. }
  76. /* This is now endian dependent */
  77. #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
  78. #define HI    1
  79. #define LO    0
  80. #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
  81. #define HI    0
  82. #define LO    1
  83. #endif
  84. static void Blit1to2(SDL_BlitInfo *info)
  85. {
  86. #ifndef USE_DUFFS_LOOP
  87.     int c;
  88. #endif
  89.     int width, height;
  90.     Uint8 *src, *dst;
  91.     Uint16 *map;
  92.     int srcskip, dstskip;
  93.  
  94.     /* Set up some basic variables */
  95.     width = info->d_width;
  96.     height = info->d_height;
  97.     src = info->s_pixels;
  98.     srcskip = info->s_skip;
  99.     dst = info->d_pixels;
  100.     dstskip = info->d_skip;
  101.     map = (Uint16 *)info->table;
  102.  
  103. #ifdef USE_DUFFS_LOOP
  104.     while ( height-- ) {
  105.         DUFFS_LOOP(
  106.         {
  107.             *(Uint16 *)dst = map[*src++];
  108.             dst += 2;
  109.         },
  110.         width);
  111.         src += srcskip;
  112.         dst += dstskip;
  113.     }
  114. #else
  115.     /* Memory align at 4-byte boundary, if necessary */
  116.     if ( (long)dst & 0x03 ) {
  117.         /* Don't do anything if width is 0 */
  118.         if ( width == 0 ) {
  119.             return;
  120.         }
  121.         --width;
  122.  
  123.         while ( height-- ) {
  124.             /* Perform copy alignment */
  125.             *(Uint16 *)dst = map[*src++];
  126.             dst += 2;
  127.  
  128.             /* Copy in 4 pixel chunks */
  129.             for ( c=width/4; c; --c ) {
  130.                 *(Uint32 *)dst =
  131.                     (map[src[HI]]<<16)|(map[src[LO]]);
  132.                 src += 2;
  133.                 dst += 4;
  134.                 *(Uint32 *)dst =
  135.                     (map[src[HI]]<<16)|(map[src[LO]]);
  136.                 src += 2;
  137.                 dst += 4;
  138.             }
  139.             /* Get any leftovers */
  140.             switch (width % 4) {
  141.                 case 3:
  142.                     *(Uint16 *)dst = map[*src++];
  143.                     dst += 2;
  144.                 case 2:
  145.                     *(Uint32 *)dst =
  146.                       (map[src[HI]]<<16)|(map[src[LO]]);
  147.                     src += 2;
  148.                     dst += 4;
  149.                     break;
  150.                 case 1:
  151.                     *(Uint16 *)dst = map[*src++];
  152.                     dst += 2;
  153.                     break;
  154.             }
  155.             src += srcskip;
  156.             dst += dstskip;
  157.         }
  158.     } else { 
  159.         while ( height-- ) {
  160.             /* Copy in 4 pixel chunks */
  161.             for ( c=width/4; c; --c ) {
  162.                 *(Uint32 *)dst =
  163.                     (map[src[HI]]<<16)|(map[src[LO]]);
  164.                 src += 2;
  165.                 dst += 4;
  166.                 *(Uint32 *)dst =
  167.                     (map[src[HI]]<<16)|(map[src[LO]]);
  168.                 src += 2;
  169.                 dst += 4;
  170.             }
  171.             /* Get any leftovers */
  172.             switch (width % 4) {
  173.                 case 3:
  174.                     *(Uint16 *)dst = map[*src++];
  175.                     dst += 2;
  176.                 case 2:
  177.                     *(Uint32 *)dst =
  178.                       (map[src[HI]]<<16)|(map[src[LO]]);
  179.                     src += 2;
  180.                     dst += 4;
  181.                     break;
  182.                 case 1:
  183.                     *(Uint16 *)dst = map[*src++];
  184.                     dst += 2;
  185.                     break;
  186.             }
  187.             src += srcskip;
  188.             dst += dstskip;
  189.         }
  190.     }
  191. #endif /* USE_DUFFS_LOOP */
  192. }
  193. static void Blit1to3(SDL_BlitInfo *info)
  194. {
  195. #ifndef USE_DUFFS_LOOP
  196.     int c;
  197. #endif
  198.     int o;
  199.     int width, height;
  200.     Uint8 *src, *map, *dst;
  201.     int srcskip, dstskip;
  202.  
  203.     /* Set up some basic variables */
  204.     width = info->d_width;
  205.     height = info->d_height;
  206.     src = info->s_pixels;
  207.     srcskip = info->s_skip;
  208.     dst = info->d_pixels;
  209.     dstskip = info->d_skip;
  210.     map = info->table;
  211.  
  212.     while ( height-- ) {
  213. #ifdef USE_DUFFS_LOOP
  214.         DUFFS_LOOP(
  215.             {
  216.                 o = *src * 4;
  217.                 dst[0] = map[o++];
  218.                 dst[1] = map[o++];
  219.                 dst[2] = map[o++];
  220.             }
  221.             src++;
  222.             dst += 3;
  223.         , width);
  224. #else
  225.         for ( c=width; c; --c ) {
  226.             o = *src * 4;
  227.             dst[0] = map[o++];
  228.             dst[1] = map[o++];
  229.             dst[2] = map[o++];
  230.             src++;
  231.             dst += 3;
  232.         }
  233. #endif /* USE_DUFFS_LOOP */
  234.         src += srcskip;
  235.         dst += dstskip;
  236.     }
  237. }
  238. static void Blit1to4(SDL_BlitInfo *info)
  239. {
  240. #ifndef USE_DUFFS_LOOP
  241.     int c;
  242. #endif
  243.     int width, height;
  244.     Uint8 *src;
  245.     Uint32 *map, *dst;
  246.     int srcskip, dstskip;
  247.  
  248.     /* Set up some basic variables */
  249.     width = info->d_width;
  250.     height = info->d_height;
  251.     src = info->s_pixels;
  252.     srcskip = info->s_skip;
  253.     dst = (Uint32 *)info->d_pixels;
  254.     dstskip = info->d_skip/4;
  255.     map = (Uint32 *)info->table;
  256.  
  257.     while ( height-- ) {
  258. #ifdef USE_DUFFS_LOOP
  259.         DUFFS_LOOP(
  260.             *dst++ = map[*src++];
  261.         , width);
  262. #else
  263.         for ( c=width/4; c; --c ) {
  264.             *dst++ = map[*src++];
  265.             *dst++ = map[*src++];
  266.             *dst++ = map[*src++];
  267.             *dst++ = map[*src++];
  268.         }
  269.         switch ( width % 4 ) {
  270.             case 3:
  271.                 *dst++ = map[*src++];
  272.             case 2:
  273.                 *dst++ = map[*src++];
  274.             case 1:
  275.                 *dst++ = map[*src++];
  276.         }
  277. #endif /* USE_DUFFS_LOOP */
  278.         src += srcskip;
  279.         dst += dstskip;
  280.     }
  281. }
  282.  
  283. static void Blit1to1Key(SDL_BlitInfo *info)
  284. {
  285.     int width = info->d_width;
  286.     int height = info->d_height;
  287.     Uint8 *src = info->s_pixels;
  288.     int srcskip = info->s_skip;
  289.     Uint8 *dst = info->d_pixels;
  290.     int dstskip = info->d_skip;
  291.     Uint8 *palmap = info->table;
  292.     Uint32 ckey = info->src->colorkey;
  293.         
  294.     if ( palmap ) {
  295.         while ( height-- ) {
  296.             DUFFS_LOOP(
  297.             {
  298.                 if ( *src != ckey ) {
  299.                   *dst = palmap[*src];
  300.                 }
  301.                 dst++;
  302.                 src++;
  303.             },
  304.             width);
  305.             src += srcskip;
  306.             dst += dstskip;
  307.         }
  308.     } else {
  309.         while ( height-- ) {
  310.             DUFFS_LOOP(
  311.             {
  312.                 if ( *src != ckey ) {
  313.                   *dst = *src;
  314.                 }
  315.                 dst++;
  316.                 src++;
  317.             },
  318.             width);
  319.             src += srcskip;
  320.             dst += dstskip;
  321.         }
  322.     }
  323. }
  324.  
  325. static void Blit1to2Key(SDL_BlitInfo *info)
  326. {
  327.     int width = info->d_width;
  328.     int height = info->d_height;
  329.     Uint8 *src = info->s_pixels;
  330.     int srcskip = info->s_skip;
  331.     Uint16 *dstp = (Uint16 *)info->d_pixels;
  332.     int dstskip = info->d_skip;
  333.     Uint16 *palmap = (Uint16 *)info->table;
  334.     Uint32 ckey = info->src->colorkey;
  335.  
  336.     /* Set up some basic variables */
  337.     dstskip /= 2;
  338.  
  339.     while ( height-- ) {
  340.         DUFFS_LOOP(
  341.         {
  342.             if ( *src != ckey ) {
  343.                 *dstp=palmap[*src];
  344.             }
  345.             src++;
  346.             dstp++;
  347.         },
  348.         width);
  349.         src += srcskip;
  350.         dstp += dstskip;
  351.     }
  352. }
  353.  
  354. static void Blit1to3Key(SDL_BlitInfo *info)
  355. {
  356.     int width = info->d_width;
  357.     int height = info->d_height;
  358.     Uint8 *src = info->s_pixels;
  359.     int srcskip = info->s_skip;
  360.     Uint8 *dst = info->d_pixels;
  361.     int dstskip = info->d_skip;
  362.     Uint8 *palmap = info->table;
  363.     Uint32 ckey = info->src->colorkey;
  364.     int o;
  365.  
  366.     while ( height-- ) {
  367.         DUFFS_LOOP(
  368.         {
  369.             if ( *src != ckey ) {
  370.                 o = *src * 4;
  371.                 dst[0] = palmap[o++];
  372.                 dst[1] = palmap[o++];
  373.                 dst[2] = palmap[o++];
  374.             }
  375.             src++;
  376.             dst += 3;
  377.         },
  378.         width);
  379.         src += srcskip;
  380.         dst += dstskip;
  381.     }
  382. }
  383.  
  384. static void Blit1to4Key(SDL_BlitInfo *info)
  385. {
  386.     int width = info->d_width;
  387.     int height = info->d_height;
  388.     Uint8 *src = info->s_pixels;
  389.     int srcskip = info->s_skip;
  390.     Uint32 *dstp = (Uint32 *)info->d_pixels;
  391.     int dstskip = info->d_skip;
  392.     Uint32 *palmap = (Uint32 *)info->table;
  393.     Uint32 ckey = info->src->colorkey;
  394.  
  395.     /* Set up some basic variables */
  396.     dstskip /= 4;
  397.  
  398.     while ( height-- ) {
  399.         DUFFS_LOOP(
  400.         {
  401.             if ( *src != ckey ) {
  402.                 *dstp = palmap[*src];
  403.             }
  404.             src++;
  405.             dstp++;
  406.         },
  407.         width);
  408.         src += srcskip;
  409.         dstp += dstskip;
  410.     }
  411. }
  412.  
  413. static void Blit1toNAlpha(SDL_BlitInfo *info)
  414. {
  415.     int width = info->d_width;
  416.     int height = info->d_height;
  417.     Uint8 *src = info->s_pixels;
  418.     int srcskip = info->s_skip;
  419.     Uint8 *dst = info->d_pixels;
  420.     int dstskip = info->d_skip;
  421.     SDL_PixelFormat *dstfmt = info->dst;
  422.     const SDL_Color *srcpal    = info->src->palette->colors;
  423.     int dstbpp;
  424.     const int A = info->src->alpha;
  425.  
  426.     /* Set up some basic variables */
  427.     dstbpp = dstfmt->BytesPerPixel;
  428.  
  429.     while ( height-- ) {
  430.             int sR, sG, sB;
  431.         int dR, dG, dB;
  432.             DUFFS_LOOP4(
  433.             {
  434.                     Uint32 pixel;
  435.                 sR = srcpal[*src].r;
  436.                 sG = srcpal[*src].g;
  437.                 sB = srcpal[*src].b;
  438.                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
  439.                          pixel, dR, dG, dB);
  440.                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  441.                   ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  442.                 src++;
  443.                 dst += dstbpp;
  444.             },
  445.             width);
  446.         src += srcskip;
  447.         dst += dstskip;
  448.     }
  449. }
  450.  
  451. static void Blit1toNAlphaKey(SDL_BlitInfo *info)
  452. {
  453.     int width = info->d_width;
  454.     int height = info->d_height;
  455.     Uint8 *src = info->s_pixels;
  456.     int srcskip = info->s_skip;
  457.     Uint8 *dst = info->d_pixels;
  458.     int dstskip = info->d_skip;
  459.     SDL_PixelFormat *srcfmt = info->src;
  460.     SDL_PixelFormat *dstfmt = info->dst;
  461.     const SDL_Color *srcpal    = info->src->palette->colors;
  462.     Uint32 ckey = srcfmt->colorkey;
  463.     int dstbpp;
  464.     const int A = srcfmt->alpha;
  465.  
  466.     /* Set up some basic variables */
  467.     dstbpp = dstfmt->BytesPerPixel;
  468.  
  469.     while ( height-- ) {
  470.             int sR, sG, sB;
  471.         int dR, dG, dB;
  472.         DUFFS_LOOP(
  473.         {
  474.             if ( *src != ckey ) {
  475.                     Uint32 pixel;
  476.                 sR = srcpal[*src].r;
  477.                 sG = srcpal[*src].g;
  478.                 sB = srcpal[*src].b;
  479.                 DISEMBLE_RGB(dst, dstbpp, dstfmt,
  480.                             pixel, dR, dG, dB);
  481.                 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  482.                   ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  483.             }
  484.             src++;
  485.             dst += dstbpp;
  486.         },
  487.         width);
  488.         src += srcskip;
  489.         dst += dstskip;
  490.     }
  491. }
  492.  
  493. static SDL_loblit one_blit[] = {
  494.     NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
  495. };
  496.  
  497. static SDL_loblit one_blitkey[] = {
  498.         NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
  499. };
  500.  
  501. SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
  502. {
  503.     int which;
  504.     SDL_PixelFormat *dstfmt;
  505.  
  506.     dstfmt = surface->map->dst->format;
  507.     if ( dstfmt->BitsPerPixel < 8 ) {
  508.         which = 0;
  509.     } else {
  510.         which = dstfmt->BytesPerPixel;
  511.     }
  512.     switch(blit_index) {
  513.     case 0:            /* copy */
  514.         return one_blit[which];
  515.  
  516.     case 1:            /* colorkey */
  517.         return one_blitkey[which];
  518.  
  519.     case 2:            /* alpha */
  520.         /* Supporting 8bpp->8bpp alpha is doable but requires lots of
  521.            tables which consume space and takes time to precompute,
  522.            so is better left to the user */
  523.         return which >= 2 ? Blit1toNAlpha : NULL;
  524.  
  525.     case 3:            /* alpha + colorkey */
  526.         return which >= 2 ? Blit1toNAlphaKey : NULL;
  527.  
  528.     }
  529.     return NULL;
  530. }
  531.